package com.qitianyong.selfclass;

import android.media.MediaCodec;
import android.media.MediaFormat;
import android.view.Surface;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by qitianyong on 2017/3/16.
 * 硬解码
 */

public class HardDecoder {

    private final static String MIME_TYPE = "video/avc";
    private MediaCodec __Codec;
    private Lock __lock = new ReentrantLock();
    private int __count = 0;

    public HardDecoder(int width, int height, Surface surface){
        try {
            __Codec = MediaCodec.createDecoderByType(MIME_TYPE);
        } catch (IOException e) {
            e.printStackTrace();
        }

        if(__Codec != null) {
            MediaFormat mediaFormat = MediaFormat.createVideoFormat(MIME_TYPE,
                    width, height);
            __Codec.configure(mediaFormat, surface, null, 0);
            __Codec.start();

            LogUtils.i("mycodec", "codec ok");
        }else{
            LogUtils.i("mycodec", "codec err");
        }
    }

    public void Destroy(){

        __lock.lock();
        if(__Codec != null){
            __Codec.stop();
            __Codec.release();
            __Codec = null;

            LogUtils.i("mycodec", "release codec ok");
        }
        __lock.unlock();
    }

    public boolean Decoder(byte[] data, int length){

        __lock.lock();
        if (__Codec != null) {
            ByteBuffer[] inputBuffers = __Codec.getInputBuffers();
            int inputBufferIndex = __Codec.dequeueInputBuffer(-1);
            if (inputBufferIndex >= 0) {
                ByteBuffer inputBuffer = inputBuffers[inputBufferIndex];
                inputBuffer.clear();
                inputBuffer.put(data, 0, length);
                __Codec.queueInputBuffer(inputBufferIndex, 0, length, __count * 200, 0);
                __count++;

                //LogUtils.i("mcodec", "dequeueInputBuffer ok");
            } else {
                __lock.unlock();
                //LogUtils.i("mycodec", "dequeueInputBuffer err");
                return false;
            }

            // Get output buffer index
            MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
            int outputBufferIndex = __Codec.dequeueOutputBuffer(bufferInfo, 100);
            while (outputBufferIndex >= 0) {
                __Codec.releaseOutputBuffer(outputBufferIndex, true);
                outputBufferIndex = __Codec.dequeueOutputBuffer(bufferInfo, 0);
            }
        }

        __lock.unlock();
        return true;
    }
}
